/** @file

Copyright (c) 2006-2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.

You may not reproduce, distribute, publish, display, perform, modify, adapt,
transmit, broadcast, present, recite, release, license or otherwise exploit
any part of this publication in any form, by any means, without the prior
written permission of Kunlun Technology (Beijing) Co., Ltd..

**/

#ifndef SPI_SERVICE_DXE_H_
#define SPI_SERVICE_DXE_H_

#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#define FLASH_MAX_NAME_LENG 32

typedef struct _EFI_SPI_SERVICE_PROTOCOL EFI_SPI_SERVICE_PROTOCOL;

#define BE4KSIZE   0x1000   /* 4K Byte block Rrase, Sector Erase */
#define BE16KSIZE  0x10000  /* 16K Byte block Rrase, Sector Erase */

typedef enum {
  EfiWidthUint8  = 0x1,
  EfiWidthUint16 = 0x2,
  EfiWidthUint32 = 0x4,
  EfiWidthUint64 = 0x8
} EFI_SPI_SERVICE_PROTOCOL_WIDTH;


typedef struct{
  UINT8   VendorId;
  UINT8   DeviceId;
  CHAR8   VendorName[FLASH_MAX_NAME_LENG];
  CHAR8   DeviceName[FLASH_MAX_NAME_LENG];
}FLASH_IDENTIFICATION;

typedef struct{
  UINT32  Size;
  UINT32  NumOfSector;
  UINT32  NumOfBlock;
}FLASH_LAYOUT;

typedef struct{
  EFI_LOCK                      Lock;
  FLASH_LAYOUT                  Layout;
  FLASH_IDENTIFICATION          Id;
  UINT8                         ErasePolarity;
}FLASH_INFO;


typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_READ) (
  IN EFI_SPI_SERVICE_PROTOCOL               *This,
  IN EFI_SPI_SERVICE_PROTOCOL_WIDTH         Width,
  IN UINTN      Count,
  IN UINTN      Offset,
  IN OUT VOID  *Buffer
);

typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_WRITE) (
  IN EFI_SPI_SERVICE_PROTOCOL               *This,
  IN EFI_SPI_SERVICE_PROTOCOL_WIDTH         Width,
  IN UINTN      Count,
  IN UINTN      Offset,
  IN OUT VOID  *Buffer
);


typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_ERASE) (
  IN EFI_SPI_SERVICE_PROTOCOL               *This,
  IN EFI_SPI_SERVICE_PROTOCOL_WIDTH         Width,
  IN UINTN      Count,
  IN UINTN      Offset
);

typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_ERASE_BLOCK) (
  IN EFI_SPI_SERVICE_PROTOCOL               *This,
  IN EFI_SPI_SERVICE_PROTOCOL_WIDTH         Width,
  IN UINTN      Count,
  IN UINTN      Offset
);

#if 0
typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_UPDATE) (
  IN EFI_SPI_SERVICE_PROTOCOL               *This,
  IN EFI_SPI_SERVICE_PROTOCOL_WIDTH         Width,
  IN UINTN      Count,
  IN UINTN      Offset,
  IN OUT VOID  *Buffer
);
#endif

typedef
EFI_STATUS
(EFIAPI *EFI_SPI_SERVICE_GET_INFO) (
IN  EFI_SPI_SERVICE_PROTOCOL        *This,
OUT FLASH_INFO                      *FlashInfo
);


struct _EFI_SPI_SERVICE_PROTOCOL{
  EFI_SPI_SERVICE_READ              Read;
  EFI_SPI_SERVICE_WRITE             Write;
  EFI_SPI_SERVICE_ERASE             Erase;
  EFI_SPI_SERVICE_ERASE_BLOCK       EraseBlock;
  EFI_SPI_SERVICE_GET_INFO          GetInfo;
};



extern EFI_GUID gEfiSpiServiceProtocolGuid;

#endif
